using namespace std;
#include"STL.h"
using namespace xtb;
STL::STL(const char* stl)
{
	_size = strlen(stl);
	_capacity = _size;
	_stl = new char[_size + 1];
	strcpy(_stl, stl);
}
typedef char* iterator;
typedef const char* const_iterator;
void STL::swap(STL& s)
{
	std::swap(_stl, s._stl);
	std::swap(_size, s._size);
	std::swap(_capacity, s._capacity);
}
STL::~STL()
{
	delete[]_stl;
	_stl = nullptr;
	_size = _capacity = 0;
}
//DAY2
void STL::reserve(size_t n)
{
	if (n > _capacity)
	{
		char* tmp = new char[n + 1];
		strcpy(tmp, _stl);
		delete[]_stl;
		_stl = tmp;
		_capacity = n;
	}
}
void STL::push_back(const char ch)
{
	if (_size == _capacity)
	{
		size_t new_capacity = _capacity == 0 ? 4 : _capacity * 2;
		reserve(new_capacity);
	}
	_stl[_size] = ch;
	_size++;
	_stl[_size] = '\0';
}
void STL::apponed(const STL& stl)
{
	size_t len = stl._size;
	if (len + _size > _capacity)
	{
		reserve(len + _size);
	}
	strcpy(_stl + _size, stl._stl);
	_size += len;
}
void STL::apponed(const char* stl)
{
	size_t len = strlen(stl);
	if (len + _size > _capacity)
	{
		reserve(len + _size);
	}
	strcpy(_stl + _size, stl);
	_size += len;
}
STL& STL::operator+=(const char ch)
{
	push_back(ch);
	return *this;
}
STL& STL::operator+=(const char* stl)
{
	apponed(stl);
	return *this;
}
STL& STL::operator+=(const STL& stl)
{
	apponed(stl);
	return *this;
}
void STL::inserst(size_t pos, char ch)
{
	assert(pos <= _capacity);
	if (_size == _capacity)
	{
		size_t new_capacity = _capacity == 0 ? 4 : _capacity * 2;
		reserve(new_capacity);
	}
	size_t end = _size + 1;
	while (end > pos)
	{
		_stl[end] = _stl[end - 1];
		end--;
	}
	_stl[pos] = ch;
	_size++;
}
void STL::inserst(size_t pos, const char* tmp)
{
	size_t len = strlen(tmp);
	if (len + _size > _capacity)
	{
		reserve(len + _size);
	}
	size_t end = _size + len;
	while (end - pos >= len)
	{
		_stl[end] = _stl[end - len];
		--end;
	}
	strncpy(_stl + pos, tmp, len);
	_size += len;
}
void STL::erase(size_t pos, size_t n)
{
	assert(pos < _size);
	if (n == npos || pos + n >= _size)
	{
		_stl[pos] = '\0';
		_size = pos;
	}
	else
	{
		//size_t i = 0;
		//while (i < n)
		//{
		//	_stl[pos + i] = _stl[pos + i + n];
		//	i++;
		//}
		//_size -=n;
		//_stl[_size] = '\0';
		strcpy(_stl + pos, _stl + pos + n);
		_size = n;
	}
}
size_t STL::find(char ch, size_t pos)
{
	for (size_t i = pos; i < _size; i++)
	{
		if (ch == _stl[i])
		{
			return i;
		}
	}
	return npos;
}
size_t STL::find(const char* stl, size_t pos)
{
	const char* ptr = strstr(_stl + pos, stl);
	if (ptr == nullptr)
	{
		return npos;
	}
	else
	{
		return ptr - _stl;
	}
}
//DAY3
STL& STL::operator=(STL stl)
{
	//if (this != &stl)
	//{
	//	char* tmp= new char[stl._capacity + 1];
	//	strcpy(tmp, stl._stl);
	//	delete[]_stl;
	//	_stl = tmp;
	//	_size = stl._size;
	//	_capacity = stl._capacity;
	//}
	swap(stl);
	return *this;
}
STL STL::substr(size_t pos, size_t len )
{
	assert(pos < _size);
	size_t end = pos + len;
	if (len == npos || len + pos >= _size)
	{
		size_t end = _size;
	}
	STL s1;
	char* tmp = new char[len + 1];
	strncpy(tmp, _stl + pos, len);
	tmp[len] = '\0';
	delete s1._stl;
	s1._stl = tmp;
	s1._size = len;
	s1._capacity = len;
	return s1;
	//size_t end = pos + len;
	//STL str;
	//str.reserve(end - pos);
	//for (size_t i = pos; i < end; i++)
	//{
	//	str += _stl[i];
	//}
	//return str;
}
ostream& xtb::operator<<(ostream& out, STL& s)
{
	for (auto ch : s)
	{
		cout << ch;
	}
	cout << endl;
	return out;
}
istream& xtb::operator>>(istream& in, STL& s)
{
	char ch;
	ch = in.get();
	char buffer[128] = { 0 };
	int i = 0;
	while (ch != ' ' && ch != '\0')
	{
		buffer[i] = ch;
		i++;
		if (i == 127)
		{
			buffer[127] = '\0';
			s += buffer;
			i = 0;
		}
		ch = in.get();
	}
	if (i > 0)
	{
		buffer[i] = '\0';
		s += buffer;
	}
	return in;
}